/****************************************************************************
 *  QLyrics - A simple lyrics viewer.                                       *
 *  Copyright (C) 2008  hsys <hanshuiys@gmail.com>                          *
 *                                                                          *
 *  This program is free software; you can redistribute it and/or modify    *
 *  it under the terms of the GNU General Public License as published by    *
 *  the Free Software Foundation; either version 3 of the License, or       *
 *  (at your option) any later version.                                     *
 *                                                                          *
 *  This program is distributed in the hope that it will be useful,         *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 *  GNU General Public License for more details.                            *
 *                                                                          *
 *  You should have received a copy of the GNU General Public License       *
 *  along with this program; if not, write to the Free Software Foundation, *
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA       *
 ****************************************************************************/

#ifndef _PLAYER_H_
#define _PLAYER_H_

#include <QObject>
#include <QLocalSocket>
#include "basictype.h"

/** This class is used to communicate with music player. */
class Player : public QObject {
    Q_OBJECT
public:
    /** Player status. */
    enum Status {
        Playing = 1,
        Paused  = 2,
        Idle    = 3,
        Closed  = 4
    };

    bool connectToPlayer(QString serverName);
    /** Send a request of track time to player, and return the function immediately. */
    void updatePlaybackTime();
    /** Get current play position. */
    LyricsTime getPlaybackTime() const { return m_offset; };
    /** Get the information of the currently playing track. */
    const Track& getTrack();
    /** Get current player status. */
    const Status& getStatus() const { return m_status; };
    /** Get the pointer of instance of the class, since the class is a singleton. */
    static void buildInstance(QObject* parent = 0);
    static Player* getInstance();

private:
    /** The id of requset event that is sent to player. */
    enum RequestEvent {
        RequestTime = 0,
        RequestTitle = 1,
        RequestAlbum = 2,
        RequestArtist = 3,
        RequestLength = 4,
        RequestFilename = 5,
        RequestExit = 6,
        RequestEnd = 7      // flag used to find the length
    };
    /** The id of response that receives from player. */
    enum ResponseEvent {
        ResponseTime = 0,
        ResponseTitle = 1,
        ResponseAlbum = 2,
        ResponseArtist = 3,
        ResponseLength = 4,
        ResponseFilename = 5,
        ResponseExit = 6,
        ResponseStatusChange = 100,
        ResponseTrackChange = 101,
        ResponseConfigure = 102
    };
    //static const ResponseEvent responseForRequest[8];


    Track m_track;
    LyricsTime m_offset;
    Status m_status;

    QLocalSocket m_pipe;

    // simple flag for synchronization between threads
    bool isWaiting[RequestEnd];
    //RequestEvent waitingId;

    static Player* sm_inst;

    /** Construct an instance and start listening. */
    Player(QObject* parent = 0);
    /** Notify the player that i'm going to exit. */
    ~Player();

    /** Send a request. */
    void sendRequestEvent(RequestEvent, bool = false);
    /** Send a request and lock the thread to wait for reply. */
    //void fetchAndWait(RequestEvent);
    void parseEvent(ResponseEvent e, QString param);

private slots:
    void readFromPlayer();

signals:
    void trackChanged();
    void statusChanged(Player::Status);
    void timeChanged(LyricsTime);
    void exit();
    void configure();
};

#endif
